package ar.edu.itba.cg.model;

import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.geometry.PhysicsCapsule;
import com.jmex.physics.geometry.PhysicsCylinder;
import com.jmex.physics.material.Material;

public class Pin {
	
	private final static float RADIUS = 3*1.5f; 
	private final static float HEIGHT = 16*1.5f;

	private static final float EPSILON_Y = 4;
	private static final float EPSILON_X = 7;
	private static final float EPSILON_Z = 7; 	
	
	private DynamicPhysicsNode node;
	private Vector3f origin;
	private boolean detach;


	public Pin(DynamicPhysicsNode node, Vector3f origin) {
		this.node = node;
		
		this.origin= new Vector3f(origin);
		setup();
		setupPhysic();
		node.getLocalTranslation().set(origin);
		detach=false;
	}

	public void resetPos() {
		setupPhysic();
		node.rest();		
		node.setActive(true);
		node.setLocalRotation(new Quaternion(new float[]{0, 0, 0}));
		node.setLinearVelocity(new Vector3f(0,0,0));
		node.setAngularVelocity(new Vector3f(0,0,0));		
		node.setAffectedByGravity(true);
		node.getLocalTranslation().set(origin);
		
		System.out.println("rotation x:" + node.getWorldRotation().x + " y: " + node.getWorldRotation().y + " z: " + node.getWorldRotation().z + " w: " + node.getWorldRotation().w);
		
	}

	public boolean isOutTheCourt() {
		return true;
	}

	public boolean isFallen() {
		if(detach)
			return false;
		
		return (origin.getY()-node.getLocalTranslation().getY())>EPSILON_Y
		|| Math.abs(origin.getX()-node.getLocalTranslation().getX())>EPSILON_X
		|| Math.abs(origin.getZ()-node.getLocalTranslation().getZ())>EPSILON_Z;
		


	}

	public void setup() {
		/* Load the ball model */
		Node model = FactoryModel.loadPin();
		model.setLocalScale(1.5f);
		/* Setup the ball physics */
		model.getLocalTranslation().set(new Vector3f());

		node.attachChild(model);
		
		final Vector3f vec1 = new Vector3f(0,0,1);//(new LineSegment(new Vector3f(), new Vector3f(0, 0, 1))).getDirection();
		final Vector3f vec2 = new Vector3f(vec1.z, vec1.x, vec1.y);
		final Vector3f vec3 = new Vector3f(vec1.y, vec1.z, vec1.x);

		PhysicsCapsule up = node.createCapsule("up");
		up.getLocalScale().set(RADIUS * 0.5f, RADIUS * 0.5f, HEIGHT * 0.45f);
		up.getLocalRotation().fromAxes(vec1, vec2, vec3);
		up.getLocalTranslation().setY(HEIGHT * 0.7f);
		
		PhysicsCapsule medium = node.createCapsule("medium");
		medium.getLocalScale().set(RADIUS * 1f, RADIUS * 1f, HEIGHT * 0.5f);
		medium.getLocalRotation().fromAxes(vec1, vec2, vec3);
		medium.getLocalTranslation().setY(-HEIGHT * 0f);

		PhysicsCylinder down = node.createCylinder("down");

		down.getLocalRotation().fromAxes(vec1, vec2, vec3);
		down.getLocalScale().set(RADIUS*0.9f, RADIUS*0.9f, HEIGHT * 0.10f);
		down.getLocalTranslation().setY(-HEIGHT * 0.45f);

		node.updateModelBound();
		
	}
	
	private void setupPhysic(){
		node.generatePhysicsGeometry();
		node.setMaterial(Material.PLASTIC);
		node.computeMass();
		//node.setMass(1.25f);
		
		node.setAffectedByGravity(true);
		
		//node.setCenterOfMass(new Vector3f(0, -HEIGHT * 0.23f, 0));
	}


	public Vector3f getPos(){
		return node.getLocalTranslation();
	}

	public DynamicPhysicsNode getNode() {
		return node;
	}

	public void setDetach(boolean b) {
		node.getLocalTranslation().set(new Vector3f(0,-100, 0));
		detach = b;
	}
	
	public boolean getDetach(){
		return detach;
	}
	
	
}
